/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package semiSupervise;

import java.net.URI;
import java.util.ArrayList;
import jwnl.JWNLDistances;
import org.semanticweb.owl.apibinding.OWLManager;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLOntologyCreationException;
import org.semanticweb.owl.model.OWLOntologyManager;
import XMLParsing.PartitionFileCreator;

public class partitionnementMoy {

    ArrayList<Element> Ens; // Ensemble des classes
    ArrayList<Ensemble> EC; // Ensemble des Groupes de Classes
    JWNLDistances d;

    partitionnementMoy() {
        Ens = new ArrayList<Element>();
        EC = new ArrayList<Ensemble>();
        d = new JWNLDistances();
        d.Initialize();
    }

    void afficherEC() {
        for (int i = 0; i < EC.size(); i++) {
            System.out.println("EC[" + i + "]= " + EC.get(i).toString());
        }
    }

    // Remplir le tableau des éléments à partir de l'ontologie
    void remplir_elements(String physicalURI) {
        OWLOntologyManager manager = null;
        OWLOntology ontology = null;
        try {
            manager = OWLManager.createOWLOntologyManager();
            URI physicalURI1 = URI.create(physicalURI);
            ontology = manager.loadOntologyFromPhysicalURI(physicalURI1);

            int i = 0;
            Element e;
            for (OWLClass cls : ontology.getReferencedClasses()) {
                e = new Element(cls.toString());
                //System.out.println("___tmp[" + (i++) + "]=" + cls.toString());
                Ens.add(e);
            }
        } catch (OWLOntologyCreationException ex) {
            System.out.println("The ontology could not be created: " + ex.getMessage());
        } finally {
            manager.removeOntology(ontology.getURI());
        }
    }

    // Remplir le tableau de groupes de façon aléatoire
    void remplir_groupes(int nbGroupes) {
        int i = 0, j = 0;
        for (i = 0; i < nbGroupes; i++) {
            EC.add(new Ensemble(Ens.get(i)));
        //System.out.println(Ens.get(numGroupe).Value + "___Groupe n°" + numElement++);
        }

        for (i = nbGroupes; i < Ens.size(); i++) {
            if (j > nbGroupes - 1) {
                j = 0;
            }
            EC.get(j++).add(Ens.get(i));
        //System.out.println(Ens.get(numGroupe).Value + "___Groupe n°" + numElement++);
        }
    }

    void traitement_Moy() {
        Element e;
        Ensemble ens;
        boolean change;
        ArrayList<String> used = new ArrayList<String>();
        do {
            change = false;
            for (int numGroupe = 0; numGroupe < EC.size(); numGroupe++) {
                int numElement = 0;
                ens = EC.get(numGroupe);
                if (ens.size() > 1) { // Si Ensemble contient plus qu'1 élément
                    while (numElement < ens.size()) {
                        int act = numGroupe;
                        e = ens.get(numElement);
                        double dIntraGroupe = 0.0, dInterGroupe = 0.0, dMin = 0.0;

                        if (!used.contains(e.toString())) {
                            used.add(e.toString());
                            // déterminer la distance intraGroupe
                            dIntraGroupe = ens.distance_intra_groupe(numElement, d);
                            System.out.println("++dIntraGroupe= " + (1 - dIntraGroupe));

                            // déterminer la distance InterGroupe
                            for (int k = 0; k < EC.size(); k++) {
                                if (k != numGroupe) {
                                    dInterGroupe = e.distance(EC.get(k), d);
                                    System.out.println("--dInterGroupe= " + (1 - dInterGroupe));
                                    if (dInterGroupe > dMin) {
                                        dMin = dInterGroupe;
                                        act = k;
                                    }
                                }
                            }// Fin calcul distance inter-classes
                        }//Fin des calculs

                        if (dMin > dIntraGroupe) {
                            change = change = deplacer_element_vers_groupe(numGroupe, numElement, act);
                        } else {
                            numElement++;
                            System.out.println("pas de changement");
                        }
                    }
                }// Si Ensemble contient plus qu'1 élément
            }
            used.clear();
        } while (change);
    }

    boolean contains(ArrayList<Ensemble> Ens, String S) {
        for (int i = 0; i < Ens.size(); i++) {
            if (EC.get(i).contains(S.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    ArrayList<Integer> determiner_groupes_proches(String s) {
        ArrayList<Integer> groupes = new ArrayList<Integer>();
        double dMin = 0.0, dSim = 0.0;
        for (int i = 0; i < EC.size(); i++) {
            dSim = EC.get(i).distance(s, d);
            System.out.println((i + 1) + ") " + (100 - dSim));
            if (dMin < dSim) {
                dMin = dSim;
                groupes.clear();
                groupes.add(i + 1);
            } else if (dMin == dSim) {
                groupes.add(i + 1);
            }
        }
        return groupes;
    }

    ArrayList<Integer> findGroup(String s) {
        if (contains(EC, s)) {
            System.out.println(s + " contenu dans Ens");
            return null;
        }

        afficherEC();
        return (ArrayList) determiner_groupes_proches(s);
    }

    boolean deplacer_element_vers_groupe(int groupeSource, int elementSource, int groupeDest) {
        System.out.println("changement plan");
        EC.get(groupeDest).add(EC.get(groupeSource).get(elementSource));
        EC.get(groupeSource).remove(elementSource);
        afficherEC();
        return true;
    }

    public void partitionMoy(String uri, int nbGroupes) {
        remplir_elements(uri);
        remplir_groupes(nbGroupes);
        afficherEC();
        traitement_Moy();
        afficherEC();
        PartitionFileCreator.createXML(EC);
    }

    public static void main(String[] args) {
        partitionnementMoy t = new partitionnementMoy();
        //t.partitionMoy("file:/C:/Users/mida/Desktop/Example/generations.owl",5);
        //t.partitionMoy("file:/C:/Users/mida/Desktop/Example/Wildlife.owl", 3);
        t.partitionMoy("file:/C:/Users/mida/Desktop/Example/Person.owl", 4);
        System.out.println("\n\nFinding groupe");
        System.out.println(t.findGroup("cat"));
    }
}
